/*
 *  loop.c
 *
 *  A Loop Queue
 *
 *  Copyright (C) 2008  Huang Guan
 *
 *  2008-7-12 Created.
 *
 *  Description: This file mainly includes the functions about 
 *
 */

#include <string.h>
#include <stdlib.h>
#include "qqdef.hpp"
#include "debug.hpp"
#include "qqpacket.hpp"
#include "loop.hpp"

static void moveToHead(loop* l,loop* r){
	typedef std::list<qqpacket*>::iterator Iter;
	for(Iter i=r->items.begin();i!=r->items.end();++i){
		l->items.push_front(*i);
	}
	r->items.clear();
}


void moveToHead(loop* l,loop* r,bool lockLeftFirst){
	if(lockLeftFirst){
		QMutexLocker ql(&l->mutex );
		QMutexLocker qr(&r->mutex );
		moveToHead(l,r);
	} else {
		QMutexLocker ql(&r->mutex );
		QMutexLocker qr(&l->mutex );
		moveToHead(l,r);
	}
}

//加到尾
int loop_push_to_tail( loop* l, qqpacket* data )
{	
	QMutexLocker ql(&l->mutex );
	l->items.push_back(data);	
	return 0;
}

//加到头
int loop_push_to_head( loop* l, qqpacket* data )
{
	QMutexLocker ql(&l->mutex );
	l->items.push_front(data);	
	return 0;
}

qqpacket* loop_pop_from_head( loop* l )
{	
	QMutexLocker ql(&l->mutex );
	if(l->items.empty()) return NULL;
	qqpacket* p=l->items.front();
	l->items.pop_front();	
	return p;
}

qqpacket* loop_pop_from_tail( loop* l )
{
	QMutexLocker ql(&l->mutex );
	if(l->items.empty()) return NULL;
	qqpacket* p=l->items.back();
	l->items.pop_back();	
	return p;
}

bool loop_remove( loop* l, qqpacket* data )
{	
	QMutexLocker ql(&l->mutex );	
	return loop_remove_without_lock(l,data,true);
}

bool loop_remove_without_lock( loop* l, qqpacket* data,bool deleteit ){	
	typedef std::list<qqpacket*>::iterator Iter;
	bool done=false;
	for(Iter i=l->items.begin();i!=l->items.end();++i){		
		if(*i == data){
			qqpacket* p=*i;
			l->items.erase(i);
			if(deleteit) delete p;
			done=true;
			break;
		}
	}
	return done;
}

qqpacket* loop_search( loop* l, void* v, loop_search_func search )
{	
	QMutexLocker ql(&l->mutex );
	return loop_search_without_lock(l,v,search);	
}

qqpacket* loop_search_without_lock( loop* l, void* v, loop_search_func search ){
	typedef std::list<qqpacket*>::iterator Iter;
	for(Iter i=l->items.begin();i!=l->items.end();++i){
		if(search(*i,v))
			return *i;
	}	
	return NULL;
}

void loop_cleanup( loop* l )
{
	
	QMutexLocker ql(&l->mutex );

	typedef std::list<qqpacket*>::iterator Iter;
	for(Iter i=l->items.begin();i!=l->items.end();++i){		
		delete *i ;
	}	
	l->items.clear();
}

int loop_is_empty( loop* l )
{
	QMutexLocker ql(&l->mutex );
	return l->items.empty();
}

